let 棋子映射, 搜索深度

const 二维数组克隆 = (arr) => {
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        newArr[i] = arr[i].slice();
    }
    return newArr;
}

class AI {
    走棋(棋子坐标, 棋子映射1, 搜索深度1) {
        棋子映射 = 棋子映射1
        搜索深度 = 搜索深度1

        let val = this.获取最佳着法(-99999, 99999, 搜索深度, 二维数组克隆(棋子坐标), -1);
        if (val && val.value != -8888) {
            let 棋子 = 棋子映射[val.key];
            return { oldX: 棋子.x, oldY: 棋子.y, newX: val.x, newY: val.y }
        } else {
            return false;
        }
    }
    是否获胜(棋子坐标, 棋子映射1, 搜索深度1) {
        棋子映射 = 棋子映射1
        搜索深度 = 搜索深度1

        let val = this.获取最佳着法(-99999, 99999, 搜索深度, 二维数组克隆(棋子坐标), 1);
        return !val || val.value == -8888
    }

    //取得棋盘上全部棋子
    获取棋盘上的全部棋子 = (map, id) => {
        let mans = [];
        for (let i = 0; i < map.length; i++) {
            for (let n = 0; n < map[i].length; n++) {
                let key = map[i][n];
                if (key && 棋子映射[key].id == id) {
                    棋子映射[key].x = n;
                    棋子映射[key].y = i;
                    mans.push(棋子映射[key])
                }
            }
        }
        return mans;
    }

    //取得棋谱所有己方棋子的着法
    获取全部着法 = (map, id) => {
        let 全部棋子 = this.获取棋盘上的全部棋子(map, id);
        let 全部着法 = [];
        // let foul = play.isFoul;
        let foul = false
        for (let i = 0; i < 全部棋子.length; i++) {
            let 棋子 = 全部棋子[i];
            let 可着点 = 棋子.可着点(map);

            for (let n = 0; n < 可着点.length; n++) {
                let x = 棋子.x;
                let y = 棋子.y;
                let newX = 可着点[n][0];
                let newY = 可着点[n][1];
                //如果不是长将着法
                if (foul[0] != x || foul[1] != y || foul[2] != newX || foul[3] != newY) {
                    全部着法.push([x, y, newX, newY, 棋子.key])
                }
            }
        }
        return 全部着法;
    }
    //A:当前棋手value/B:对手value/depth：层级
    获取最佳着法 = (A, B, depth, map, id) => {
        let rootKey
        if (depth == 0) {
            return { value: this.评估棋局(map, id) }; //局面评价函数; 
        }
        let 全部着法 = this.获取全部着法(map, id); //生成全部走法;
        //这里排序以后会增加效率
        let move, key, oldX, oldY, newX, newY, clearKey
        for (let i = 0; i < 全部着法.length; i++) {

            //走这个走法;
            move = 全部着法[i];
            key = move[4];
            oldX = move[0];
            oldY = move[1];
            newX = move[2];
            newY = move[3];
            clearKey = map[newY][newX] || "";

            map[newY][newX] = key;
            delete map[oldY][oldX];
            棋子映射[key].x = newX;
            棋子映射[key].y = newY;

            if (clearKey == "j0" || clearKey == "J0") {//被吃老将,撤消这个走法; 
                棋子映射[key].x = oldX;
                棋子映射[key].y = oldY;
                map[oldY][oldX] = key;
                delete map[newY][newX];
                if (clearKey) {
                    map[newY][newX] = clearKey;
                    // 棋子映射[ clearKey ].isShow = false;
                }

                return { "key": key, "x": newX, "y": newY, "value": 8888 };
            } else {
                let val = -this.获取最佳着法(-B, -A, depth - 1, map, -id).value;

                //撤消这个走法;　 
                棋子映射[key].x = oldX;
                棋子映射[key].y = oldY;
                map[oldY][oldX] = key;
                delete map[newY][newX];
                if (clearKey) {
                    map[newY][newX] = clearKey;
                    //棋子映射[ clearKey ].isShow = true;
                }
                if (val >= B) {
                    //将这个走法记录到历史表中; 
                    return { "key": key, "x": newX, "y": newY, "value": B };
                }
                if (val > A) {
                    A = val; //设置最佳走法; 
                    if (搜索深度 == depth) {
                        rootKey = { "key": key, "x": newX, "y": newY, "value": A };
                    }
                }
            }
        }
        //将这个走法记录到历史表中; 
        if (搜索深度 == depth) {//已经递归回根了
            if (!rootKey) {
                //AI没有最佳走法，说明AI被将死了，返回false
                return false;
            } else {
                //这个就是最佳走法;
                return rootKey;
            }
        }
        return { "key": key, "x": newX, "y": newY, "value": A };
    }

    //评估棋局 取得棋盘双方棋子价值差
    评估棋局 = (map, id) => {
        let val = 0;
        for (let i = 0; i < map.length; i++) {
            for (let n = 0; n < map[i].length; n++) {
                let key = map[i][n];
                if (key) {
                    val += 棋子映射[key].value[i][n] * 棋子映射[key].id;
                }
            }
        }
        return val * id;
    }
}

export default new AI()